<template>
    <div class="files">
        <div class="files-folder">
            <folder-tree height="100%" @change="changeFolder" :defaultChange="false" />
        </div>
        <div class="files-body">
            <div class="page-action-btn files-btn">
                <el-button type="info" @click="cancelSelect" v-show="selectFiles.length>0">取消选择</el-button>
                <el-button type="primary" @click="emitInput" v-if="isSelect">确定选择</el-button>
                <p-confirm-btn @confirm="delFile" v-if="UIAuth._api_admin_file_delete"></p-confirm-btn>
                <PUpload :folderId="folder?folder.id:''" @upload="uploadCallBack" />
            </div>
            <div class="files-list" v-loading="isLoading" v-if="UIAuth._api_admin_file_paginate_get">
                <transition-group name="opacity-translateX" tag="div">
                    <div class="files-list-item" v-for="item in dataList" :key="item.id" @click="clickFile(item)" @dblclick="dbClickFile(item)">
                        <show-file :file="item" />
                        <transition name="opacity-scale-animation">
                            <div class="files-list-item-check" v-show="isFileSelect(item.id)">
                                <i class="fa fa-check-square-o"></i>
                            </div>
                        </transition>
                    </div>
                </transition-group>
            </div>
            <div class="files-page">
                <p-pagination v-model="paginate" @change="getFilesList"></p-pagination>
            </div>
        </div>

    </div>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs } from "vue";
import { useStore } from "vuex";
import FolderTree from "@/components/file/FolderTree.vue";
import config from "@/config";
import message from "@/lib/message";
import http from "@/lib/http/http";
import utils from "@/lib/utils";
import { IPaginate, defaultPaginate } from "@/lib/IApp";
import PPagination from "@/components/PPagination.vue";
import PConfirmBtn from "@/components/PConfirmBtn.vue";
import ShowFile from "@/components/file/ShowFile.vue";
import PUpload from "@/components/file/PUpload.vue";


/**
 * state 数据类型
 */
interface IState {
    isLoading: boolean;
    /**
     * 当前选择文件夹
     */
    folder: any;
    /**
     * 上传进度
     */
    percentage: number;
    /**
     * 上传文件名
     */
    fileName: string;
    /**
     * 进度条状态
     */
    status: any;
    paginate: IPaginate;
    /**
     * 数据列表
     */
    dataList: any[];
    /**
     * 当前选中图片
     */
    selectFiles: any[];
}
export default defineComponent({
    name: "Files",
    components: { FolderTree, PPagination, PConfirmBtn, ShowFile, PUpload },
    props: {
        isSelect: {
            // 是否选择模式
            type: Boolean,
            default: false,
        },
        multiple: {
            // 是否多选
            type: Boolean,
            default: false,
        },
    },
    emits: ["select"],
    setup(props, { emit }) {
        const store = useStore();
        const { UIAuth, bodySize } = toRefs(store.state);
        /**
         * 上传文件大小
         */
        const uploadSize = config.uploadSize;
        /**
         * 可上传文件类型
         */
        const fileExt: string[] = config.fileExt;
        const state = reactive<IState>({
            isLoading: false,
            folder: null,
            percentage: 0,
            fileName: "",
            status: null,
            paginate: defaultPaginate,
            dataList: [],
            selectFiles: [],
        });
        /**
         * 判断单曲图片是否选中
         */
        const isFileSelect = (id: string): boolean => {
            const index = state.selectFiles.findIndex((i: any) => i.id === id);
            return index >= 0;
        };
        /**
         * 多选文件
         */
        const multipleFiles = (file: any) => {
            const index = state.selectFiles.findIndex(
                (i: any) => i.id === file.id
            );
            if (index < 0) {
                state.selectFiles.push(file);
            } else {
                state.selectFiles.splice(index, 1);
            }
        };
        /**
         * 点击文件事件
         */
        const clickFile = (file: any) => {
            if (props.isSelect) {
                // 选择文件状态
                if (props.multiple) {
                    // 多选
                    multipleFiles(file);
                } else {
                    // 单选
                    oneFile(file);
                }
            } else {
                // 正常状态
                multipleFiles(file);
            }
        };
        // 单选
        const oneFile = (file: any) => {
            if (state.selectFiles.length === 0) {
                state.selectFiles.push(file);
            } else {
                if (state.selectFiles[0].id === file.id) {
                    state.selectFiles = [];
                } else {
                    state.selectFiles.splice(0, 1, file);
                }
            }
        };
        /**
         * 双击文件 选择文件状态，并且是单选 直接返回
         */
        const dbClickFile = (file: any) => {
            if (props.isSelect && !props.multiple) {
                emit("select", file);
            }
        };
        /**
         * 传出选中的文件
         */
        const emitInput = () => {
            if (props.isSelect) {
                // 如果是选择文件状态，就传出选中的文件
                if (props.multiple) {
                    emit("select", state.selectFiles);
                } else {
                    let file = { file_sign: "", file_name: "", file_ext: "" };
                    if (state.selectFiles.length > 0) {
                        file = state.selectFiles[0];
                    }
                    emit("select", file);
                }
                state.selectFiles = [];
            }
        };
        /**
         * 取消选项文件
         */
        const cancelSelect = () => {
            state.selectFiles = [];
        };
        /**
         * 上传回调
         */
        function uploadCallBack(file: any[] = []) {
            state.dataList.push(...file);
        }
        /**
         * 获取上传文件列表
         */
        const getFilesList = () => {
            state.isLoading = true;
            state.selectFiles = [];
            let folderId = "";
            if (!utils.empty(state.folder)) {
                folderId = state.folder.id;
            }
            http.Get(
                `/file/${state.paginate.page_size}/${state.paginate.page}`,
                {
                    folder_id: folderId,
                }
            )
                .then((data) => {
                    state.paginate = data.paginate;
                    state.dataList = data.data;
                    state.isLoading = false;
                })
                .catch((err) => (state.isLoading = false));
        };
        /**
         * 删除文件
         */
        const delFile = () => {
            const ids: string[] = [];
            if (state.selectFiles.length === 0) {
                message.error("请选择要删除的数据");
                return;
            }
            state.selectFiles.forEach((item) => {
                ids.push(item.id);
            });
            message.loadingShow("删除中");
            http.Delete("/file", { ids })
                .then((data) => {
                    ids.forEach((id: string) => {
                        const index = state.dataList.findIndex(
                            (i) => i.id === id
                        );
                        if (index >= 0) {
                            state.dataList.splice(index, 1);
                        }
                    });
                    state.selectFiles = [];
                })
                .catch((err) => "");
        };
        /**
         * 选择文件夹事件
         */
        const changeFolder = (folder: any) => {
            state.folder = folder;
            state.paginate.page = 1;
            getFilesList();
        };

        state.paginate.page_size = 20;
        getFilesList();
        return {
            UIAuth,
            bodySize,
            ...toRefs(state),
            isFileSelect,
            clickFile,
            uploadSize,
            fileExt,
            oneFile,
            dbClickFile,
            emitInput,
            cancelSelect,
            changeFolder,
            delFile,
            getFilesList,
            uploadCallBack
        };
    },
});
</script>

<style lang="scss">
.el-progress {
    display: flex;
    align-items: center;
}
</style>
<style scoped lang="scss">
.files {
    height: 100%;
    &-btn {
        margin-left: 10px;
    }
    position: relative;
    display: flex;
    justify-content: space-between;
    &-folder {
        width: 300px;
    }
    &-body {
        height: 100%;
        width: calc(100% - 300px);
        &-upload {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background-color: #f8f8f8;
            padding: 10px;
            height: 70px;
            margin-left: 10px;
            border: 1px $text-gray2-color solid;
            &-btn {
                width: 100px;
            }
            &-file {
                width: calc(100% - 100px);
                & > div {
                    &:nth-child(1) {
                        height: 25px;
                        padding-left: 15px;
                    }
                }
            }
        }
    }
    &-page {
        padding-top: 10px;
    }
    &-list {
        height: calc(100% - 80px);
        overflow: hidden;
        overflow-y: auto;
        & > div {
            position: relative;
            height: 100%;
            display: flex;
            align-content: flex-start;
            flex-wrap: wrap;
        }
        &-item {
            position: relative;
            width: 150px;
            margin-left: 10px;
            margin-top: 10px;
            height: 150px;
            &-check {
                position: absolute;
                width: calc(100% - 8px);
                height: calc(100% - 8px);
                left: 0;
                top: 0;
                padding: 0;
                box-shadow: 0 0 10px $primary-color;
                border: 4px $primary-color solid;
                border-radius: 5px;
                pointer-events: none;
                & > i {
                    font-size: 30px;
                    color: #fff;
                    background-color: $primary-color;
                    padding: 4px 5px;
                    border-bottom-right-radius: 5px;
                }
            }
        }
    }
}
</style>